﻿
//编译器类--把源程序编译为机器码程序
namespace n_Compiler
{
using System;
using n_Accidence;
using n_ATMEGA_Assembler;
using n_Box;
using n_Config;
using n_Const;
using n_ConstLink;
using n_COper;
using n_CORTEX_M0_Assembler;
using n_CPUType;
using n_Deploy;
using n_ET;
using n_FuncAndVarLink;
using n_FunctionAndVar;
using n_FunctionList;
using n_Include;
using n_KeyWord;
using n_LabelList;
using n_Macro;
using n_Malloc;
using n_MCS51_Assembler;
using n_Operation;
using n_ParseNet;
using n_PC80X86_Assembler;
using n_SPCE061A_Assembler;
using n_Struct;
using n_StructLink;
using n_StructList;
using n_Unit;
using n_UnitLink;
using n_UnitList;
using n_VarList;
using n_Vdata;
using n_VdataLink;
using n_VdataList;
using n_VM_Assembler;
using n_WordList;
using n_CDebug;
using n_Param;
using n_Opti;

public static class Compiler
{
	public const int STEP_record = 0;
	
	public const int STEP_cInitCompiler = 0;
	public const int STEP_cLoadingFile = 1;
	public const int STEP_cAccidence = 2;
	public const int STEP_cParsing = 3;
	public const int STEP_cRecording = 4;
	public const int STEP_cDeploy = 5;
	
	public const int STEP_InitCompiler = 0;
	public const int STEP_LoadingFile = 1;
	public const int STEP_Accidence = 2;
	public const int STEP_Parsing = 3;
	public const int STEP_Recording = 4;
	public const int STEP_Deploy = 5;
	public const int STEP_ApplyAddress = 6;
	public const int STEP_DeployMacro = 7;
	public const int STEP_ASMPack = 8;
	public const int STEP_InitAssemble = 9;
	public const int STEP_Assemble = 10;
	public const int STEP_OK = 11;
	public const int STEP_Number = 11;
	
	//获取检查描述
	public static string GetCheckDescribe( int StepIndex )
	{
		switch( StepIndex ) {
			case STEP_cInitCompiler:		return "准备检查...";
			case STEP_cLoadingFile:		return "检查文件完整性...";
			case STEP_cAccidence:		return "检查词法...";
			case STEP_cParsing:			return "检查语法...";
			case STEP_cRecording:		return "检查成员定义...";
			case STEP_cDeploy:			return "检查表达式...";
			default:					return "未定义的步骤: " + StepIndex;
		}
	}
	
	//获取编译进度描述
	public static string GetDescribe( int StepIndex )
	{
		switch( StepIndex ) {
			case STEP_InitCompiler:		return "初始化编译器...";
			case STEP_LoadingFile:		return "加载文件...";
			case STEP_Accidence:		return "分析词法...";
			case STEP_Parsing:			return "分析语法...";
			case STEP_Recording:		return "扫描成员定义...";
			case STEP_Deploy:			return "展开语法树...";
			case STEP_ApplyAddress:		return "分配存储空间...";
			case STEP_DeployMacro:		return "解析中间代码...";
			case STEP_ASMPack:			return "封装汇编代码...";
			case STEP_InitAssemble:		return "初始化汇编器...";
			case STEP_Assemble:			return "转换机器代码...";
			case STEP_OK:				return "";
			default:					return "未定义的步骤: " + StepIndex;
		}
	}
	
	public delegate void deleCheckStep( int StepIndex );
	public static deleCheckStep CheckStep;
	public delegate void deleCompilingStep( int StepIndex );
	public static deleCompilingStep CompilingStep;
	static void DefaultStep( int StepIndex )
	{
		//...
	}
	
	public static string Source;
	public static string[] ASMList;
	public static string[] HEXList;
	
	
	
	//仅用于仿真, 保存待编译的临时源文件
	public static string SimTempSource;
	
	//编译器启动初始化,加载系统文件
	public static void FileLoadInit()
	{
		//初始化配置类
		Config.Init();
		//加载着色词颜色列表
		KeyWord.Init();
		//加载运算符号列表
		COper.LoadFile();
		//加载运算信息表
		Operation.LoadFile();
		//加载汇编运算库
		Macro.LoadFile();
		//加载打包函数的静态链接库
		Box.LoadFile();
		//加载mcs51机器码文件
		MCS51_Assembler.LoadFile();
		//加载AVR机器码文件
		ATMEGA_Assembler.LoadFile();
		//加载spce061a机器码文件
		SPCE061A_Assembler.LoadFile();
		//加载CORTEX M0机器码文件
		CORTEX_M0_Assembler.LoadFile();
		//加载PC80X86机器码文件
		//PC80X86_Assembler.LoadFile();
		//加载虚拟机机器码文件
		VM_Assembler.LoadFile();
		
		//初始化文件加载器
		Include.Init();
		//初始化词法列表
		WordList.Init();
		//初始化词法分析器
		Accidence.Init();
		//初始化语法分析器
		ParseNet.Init();
		//初始化变量记录表
		VarList.Init();
		//初始化元件记录表
		UnitList.Init();
		//初始化虚拟数据类型列表
		VdataList.Init();
		//初始化函数记录表
		FunctionList.Init();
		//初始化结构体列表
		StructList.Init();
		//初始化流程标号表
		LabelList.Init();
		//初始化优化器
		Opti.Init();
		
		CompilingStep += DefaultStep;
		CheckStep += DefaultStep;
		
		SimTempSource = null;
	}
	
	//软件退出
	public static void Close()
	{
		Include.Close();
	}
	
	//检查语法
	public static void Check( string Path )
	{
		CheckStep( STEP_cInitCompiler );
		Reset();
		
		CheckStep( STEP_cLoadingFile );
		Source = Include.IncludeAllFile( Path );
		if( ET.isErrors() ) {
			return;
		}
		CheckStep( STEP_cAccidence );
		Accidence.CutSource( Source );
		
		CheckStep( STEP_cParsing );
		ParseNet.Parse();
		if( ET.isErrors() ) {
			return;
		}
		CheckStep( STEP_cRecording );
		if( !RecordOK() ) {
			return;
		}
		CheckStep( STEP_cDeploy );
		Deploy.TurnToSupperASM();
		if( ET.isErrors() ) {
			return;
		}
	}
	
	//编译到机器码程序
	public static string[] Compile( string Path, int OptimizeFlag )
	{
		//--------------------------------------------
		//初始化编译器
		CompilingStep( STEP_InitCompiler );
		Reset();
		Config.OptimizeFlag = OptimizeFlag;
		
		//--------------------------------------------
		//加载所有的包含文件
		CompilingStep( STEP_LoadingFile );
		Source = Include.IncludeAllFile( Path );
		
		if( ET.isErrors() ) {
			return null;
		}
		//--------------------------------------------
		//词法分析器--把源程序分隔为词组序列--输出: WordList
		CompilingStep( STEP_Accidence );
		Accidence.CutSource( Source );
		
		//--------------------------------------------
		//语法分析器--把词组序列转化成语法树--输出: ParseNet
		CompilingStep( STEP_Parsing );
		ParseNet.Parse();
		if( ET.isErrors() ) {
			return null;
		}
		//--------------------------------------------
		//遍历语法树--提取各类预编译信息
		CompilingStep( STEP_Recording );
		if( !RecordOK() ) {
			return null;
		}
		//--------------------------------------------
		//展开语法树,结果存放到代码层0中
		CompilingStep( STEP_Deploy );
		Deploy.TurnToSupperASM();
		if( ET.isErrors() ) {
			return null;
		}
		//--------------------------------------------
		//分配剩余变量地址
		CompilingStep( STEP_ApplyAddress );
		
		if( Config.GetCPU().StartsWith( CPUType.MEGA_X ) ) {
		   	ASMList = MallocAvr.ApplyAddress();
		}
		else if( Config.GetCPU() == CPUType.VM ) {
		   	ASMList = MallocAvr.ApplyAddress();
		}
		else if( Config.GetCPU().StartsWith( CPUType.MCS_X ) ) {
		   	ASMList = MallocMcs51.ApplyAddress();
		}
		else {
			n_OS.VIO.Show( "<Compile> 申请地址时遇到未知的CPU类型: " + Config.GetCPU() );
			return null;
		}
		
		if( ET.isErrors() ) {
			return null;
		}
		//--------------------------------------------
		//转换到汇编语言
		CompilingStep( STEP_DeployMacro );
		ASMList = Macro.DeployMacro( ASMList );
		if( ET.isErrors() ) {
			return null;
		}
		//--------------------------------------------
		//封装汇编程序
		CompilingStep( STEP_ASMPack );
		ASMList = Box.Pack( ASMList );
		if( ET.isErrors() ) {
			return null;
		}
		//--------------------------------------------
		//运行汇编器汇编程序
		HEXList = AssembleList( ASMList );
		
		CompilingStep( STEP_OK );
		return HEXList;
	}
	
	//重置编译器
	static void Reset()
	{
		//清除错误列表
		ET.Clear();
		//初始化调试器
		Debug.Clear();
		//清除编译配置
		Config.Reset();
		//清除编译参数
		Param.Clear();
		//复位优化器
		Opti.Reset();
	}
	
	//汇编程序组
	static string[] AssembleList( string[] Source )
	{
		n_ATMEGA_Label.ATMEGA_Label.Clear();
		
		string[] r = new string[ Source.Length ];
		for( int i = 0; i < Source.Length; ++i ) {
			Config.SetChipIndex( i );
			r[ i ] = Assemble( Source[ i ], i );
			//r[ i ] = ATMEGA_Assembler.ToHexCode( r[ i ] );
		}
		if( ET.isErrors() ) {
			return null;
		}
		for( int i = 0; i < Source.Length; ++i ) {
			if( Config.GetCPU().StartsWith( CPUType.MEGA_X ) ) {
				r[ i ] = ATMEGA_Assembler.ToHexCode( r[ i ] );
			}
			else {
				//气死人了......
				//r[ i ] = MCS51_Assembler.Assemble( r[ i ] );
			}
		}
		return r;
	}
	
	//汇编器
	static string Assemble( string Source, int Index )
	{
		string HEXCode = null;
		string CPUtype = Config.GetCPU();
		//转换到机器码
		if( Config.GetCPU().StartsWith( CPUType.MCS_X ) ) {
			HEXCode = MCS51_Assembler.Assemble( Source );
		}
		else if( CPUtype == CPUType.SPCE061A ) {
			HEXCode = SPCE061A_Assembler.Assemble( Source );
		}
		else if( CPUtype.StartsWith( CPUType.MEGA_X ) ) {
			HEXCode = ATMEGA_Assembler.Assemble( Source, Index );
		}
		else if( CPUtype == CPUType.LPC1114 ) {
			HEXCode = CORTEX_M0_Assembler.Assemble( Source );
		}
		else if( CPUtype == CPUType.PC80X86 ) {
			HEXCode = PC80X86_Assembler.Assemble( Source, Index );
		}
		else if( CPUtype == CPUType.VM ) {
			HEXCode = VM_Assembler.Assemble( Source, Index );
		}
		else {
			ET.ShowError( "未拦截的错误--未知芯片类型: " + Config.GetCPU() );
		}
		return HEXCode;
	}
	
	//提取信息
	static bool RecordOK()
	{
		n_Param.Param.UserspaceOn = false;
		
		//遍历语法树--提取元件信息
		Unit.Record();
		if( ET.isErrors() ) {
			return false;
		}
		//遍历语法树--处理元件引用成员连接
		UnitLink.Record();
		if( ET.isErrors() ) {
			return false;
		}
		//遍历语法树--提取常量信息
		Const.Record();
		if( ET.isErrors() ) {
			return false;
		}
		//遍历语法树--处理常量连接
		ConstLink.Record();
		if( ET.isErrors() ) {
			return false;
		}
		//遍历语法树--提取虚拟数据类型信息
		Vdata.Record();
		if( ET.isErrors() ) {
			return false;
		}
		//遍历语法树--处理虚拟变量引用成员连接
		VdataLink.Record();
		if( ET.isErrors() ) {
			return false;
		}
		//遍历语法树--提取结构体信息
		Struct.Record();
		if( ET.isErrors() ) {
			return false;
		}
		//遍历语法树--处理结构体引用成员连接
		StructLink.Record();
		if( ET.isErrors() ) {
			return false;
		}
		//遍历语法树--提取函数和静态变量信息
		FunctionAndVar.Record();
		if( ET.isErrors() ) {
			return false;
		}
		//遍历语法树--处理函数和变量引用成员连接
		FuncAndVarLink.Record();
		if( ET.isErrors() ) {
			return false;
		}
		return true;
	}
	
	//保存程序组
	static void Save( string[] ChipList, string ExName )
	{
		//保存文件
//		for( int i = 0; i < ChipList.Length; ++i ) {
//			if( ChipList[ i ] == null ) {
//				continue;
//			}
//			string TargetPath = A.ctext.FilePath + A.ctext.FileName + "_" + i + "." + ExName;
//			VIO.SaveTextFile( TargetPath, ChipList[ i ] );
//		}
	}
}
}






